HTML Document |
|
HTML Document in a Web Server |
When an HTML file is located in a web server, remote user can open the document using the respective URL. In this case, the browser sends a HTTP request, and the server uses HTTP to return HTML that can be displayed in the browser. Cuando un archivo de HTML se coloca en un servidor web, los usuarios remotos pueden abrir el documento usando el respectivo URL. En este caso, el explorador envía una solicitud de HTTP, y el servidor usa HTTP para regresar HTML que puede ser mostrado en el explorador. |
HTTP |
The figure below shows how the communication between the browser and the web server works. First, the browser sends an HTTP request. Second, the web server prepares and sends an HTTP response. La figura de abajo muestra cómo opera la comunicación entre el explorador y el servidor web. Primero, el explorador envía una solicitud de HTTP. Segundo, el servidor web prepare y envía una respuesta de HTTP. |
Web Application |
|
Extensible Markup Language (XML) |
|
XML Web Service |
Allow two computers to talk to each other using the Web and HTTP. A XML Web Service is not the same as a Web application. The figure below shows a web server offering three methods using XML web services; a client may use a socket to access these services. One of the main advantages of XML Web Services is that they are designed taking into consideration the offered services by the company. Additionally, the programs that will access the XML Web Services can be created in different platforms, making possible to exchange information and perform operations between two companies. Permiten a dos computadoras hablar usando la Web y HTTP. Un XML Web service no es lo mismo que una aplicación Web. La figura de abajo muestra un servidor web ofreciendo tres métodos usando XML web services; un cliente puede usar un socket para tener acceso a estos servicios. Una de las principales ventajas de los XML Web Services es que son diseñados considerando los servicios que se ofrecen en la empresa. Adicionalmente, los programas que se crean para accesar los servicios XML Web pueden estar escritos en distintas plataformas, haciendo posible intercambiar información y realizar operaciones entre dos empresas. |
Web Server |
A XML Web Service runs on a web server and offers a set of functions or methods. The web server listens port 80, and waits for HTTP request to execute the methods. In the figure below, the client sends an HTTP request following a special format known as SOAP. The web server executes the request service and returns the respective results, in this case the list of clients. Un XML Web Service corre en un servidor web y ofrece un conjunto de funciones o métodos. El servidor web escucha el puerto 80 y espera por solicitudes HTTP para ejecutar los métodos. En la figura de abajo, el cliente envía una solicitud HTTP siguiente un formato especial conocido como SOAP. El web server ejecuta el servicio solicitado y regresa los resultados respectivos, en este caso la lista de clientes. |
Simple Object Access Protocol (SOAP) |
It is a communication protocol based on XML to call remote functions that allow Internet communication between programs (applications). In a XML Web Service, the function parameters are sent using XML, after the function is called, the values returned by the function are sent back using XML. The figure below shows the main differences between a Web application and an XML Web Service. Because XML may also be used in a Web Application, there is a thin line between a Web Application and a Web Service. SOAP is independent from the platform technology than can be used from any language independent and gets around firewalls. Es un protocolo de comunicaciones basado en XML para llamar funciones remotas que permiten la comunicación a través de la Internet entre programas (aplicaciones). En un Servicio Web de XML, los parámetros de la función son enviados usando XML, después que la función es llamada, los valores retornados por la función son enviados de regreso usando XML. La figura de abajo muestra las principales diferencias entre una aplicación Web y un servicio XML Web. Debido a que XML también puede ser usado en una aplicación Web, hay una línea muy delgada entre una aplicación Web y Un servicio Web. SOAP es independiente de la plataforma, independiente del lenguaje y logra atravesar los firewalls. |
SOAP in XML |
The figure below shows how SOAP works. Because SOAP is an XML document, it must follow all the rules of XML. In the example below, the service is called Add. The service takes two parameters: a and b, and returns the result of the sum of the input values using XML. The client must process the returned XML to extract the result. The important fact about SOAP is that any client can use the service; thus, the client can be written in any programming language such as: Java, C#, or other language. La figura de abajo muestra cómo opera SOAP. Debido a que SOAP es un documento de XML, este debe seguir todas las reglas de XML. En el ejemplo de abajo, el servicio se llama Add. El servicio toma dos parámetros: a y b, y regresa la suma de los valores de entrada en formato XML. El cliente debe procesar el XML retornado para extraer el resultado. El hecho importante acerca de SOAP es que cualquier cliente puede usar el servicio; así el cliente puede ser un programa escrito en Java, C#, o cualquier otro lenguaje. |
WSDL |
Web Services Description Language is a special format using XML that is used to describe Web Services. You may place a WSDL file in the same folder where the service is located. This file has the same name of the service and provides information about the service. Web Services Description Language es un formato en XML que se utiliza para describir los Servicios Web. Usted puede colocar un archivo WSDL en la misma carpeta dónde está ubicado el servicio. Este archivo tiene el mismo nombre que el servicio y proporciona información sobre el servicio. |
Problem 1 |
Cree an IIS Web Application called MathServer using Wintempla. Cree una IIS Web Application llamada MathServer usando Wintempla. |
Step A |
Insert two buttons in the Index.cpp file as shown. Inserte dos botones en el archivo Index.cpp como se muestra. |
Step B |
Edit the Index.cpp file as shown. Edite el archivo Index.cpp como se muestra. |
Index.cpp |
. . . void Index::Window_Open(Web::HttpConnector& h) { } void Index::btAddition_onclick(Web::HttpConnector& h) { h.NavigateTo(L"Addition"); } void Index::btSubtraction_onclick(Web::HttpConnector& h) { h.NavigateTo(L"Subtraction"); } |
Step C |
Insert a new Web Page called Addition Tools > Add Wintempla Item > Web Page . Inserte una nueva página Web llamada Addition Tools > Add Wintempla Item > Web Page . |
Step D |
Use Wintempla to edit the Addition Web Page. Click on the "blue cloud" to add a Web Service called Addition as shown. Use Wintempla para editar la página Web Addition. Haga clic en la "nube azul" para agregar un Servicio Web llamado Addition como se muestra. |
Step E |
Add another Web Page called Subtraction with a Web Service called Subtraction as shown. Agregue otra página Web llamada Subtraction con un Web Service llamado Subtraction como se muestra. |
Step F |
At the top of the MathServer.cpp file include the header files for the Web pages: Addition and Subtraction. En la parte de arriba del archivo MathServer.cpp incluya los archivos de encabezado para las páginas Web: Addition y Subtraction. |
MathServer.cpp |
#include "stdafx.h" //________________________________________ MathServer.cpp #include "MathServer.h" #include "Addition.h" #include "Subtraction.h" //_______________________________________________________ Web Application ... |
Step G |
Edit the files Addition.cpp and Subtraction.cpp as shown. Edite los archivos Addition.cpp y Subtraction.cpp como se muestra. |
Addition.cpp |
. . . void Addition::Window_Open(Web::HttpConnector& h) { serviceAddition.soapEnvelope.ActionXmlns = L"http://www.ugto.mx/MathServer"; const double x = serviceAddition.GetDoubleParameter(h, L"x"); const double y= serviceAddition.GetDoubleParameter(h, L"y"); serviceAddition.Text = L"Addition"; serviceAddition.soapEnvelope.AddParameter(L"result", x+y); } |
Subtraction.cpp |
. . . void Subtraction::Window_Open(Web::HttpConnector& h) { serviceSubtraction.soapEnvelope.ActionXmlns = L"http://www.ugto.mx/MathServer"; const double x = serviceSubtraction.GetDoubleParameter(h, L"x"); const double y= serviceSubtraction.GetDoubleParameter(h, L"y"); serviceSubtraction.Text = L"Subtraction"; serviceSubtraction.soapEnvelope.AddParameter(L"result", x-y); } |
Step H |
Run and test your Web Services. Ejecute y pruebe su Web Services. |
Tip |
A XML namespace (xmlns) provides a method to avoid name conflicts in XML elements. In the previous example, both variables: x and y are declared inside the http://www.ugto.mx/MathServer namespace. As the URL is unique, the variables are also unique in the Internet (worldwide). Una namespace de XML (xmlns) proporciona un método para evitar conflictos de nombres en los elementos de XML. En el ejemplo previo, ambas variables: x y y son declaradas dentro del namespace http://www.ugto.mx/MathServer. Como el URL es único, las variables también son únicas en la Internet (en forma global). |
Problem 2 |
Publish in a Web server the MathServer Web Service. Use Anonymous Authentication. Publique en un Servidor Web el Web Service llamado MathServer. Use Autentificación Anónima. |
Problem 3 |
Cree a Dialog application using Wintempla called ClientCalculator. Then remove the comment from #define WIN_SOCKETS_SUPPORT in the file stdafx.h. Do not forget to activate the following events: the Change event in the both textboxes, and the Click event in the radio buttons. Cree una aplicación de Diálogo usando Wintempla llamada ClientCalculator. Entonces remueva los comentarios de #define WIN_SOCKETS_SUPPORT en el archivo stdafx.h. No se olvide de activar los siguientes eventos: el evento de Change en las cajas de texto y el evento Click en los radio buttons. |
Step A |
Edit the GUI of the program as shown. Edite la GUI del programa como se muestra. |
Step B |
Edit the file ClientCalculator.cpp as shown. Edite el archivo ClientCalculator.cpp como se muestra. |
ClientCalculator.h |
. . . class ClientCalculator : public Win::Dialog { public: ClientCalculator() { } ~ClientCalculator() { } Sys::SoapEnvelope soapEnvelope; void ShowHttpRequest(); void PrepareHttpRequest(Web::HttpRequest& httpRequest); . . . }; |
ClientCalculator.cpp |
. . . void ClientCalculator::Window_Open(Win::Event& e) { //_________________________________________________________ Soap Envelope setup soapEnvelope.ActionXmlns = L"http://www.ugto.mx/MathServer"; soapEnvelope.ActionName = L"Addition"; soapEnvelope.AddParameter(L"x", L"0"); soapEnvelope.AddParameter(L"y", L"0"); // radioAddition.Checked = true; // ShowHttpRequest(); } void ClientCalculator::tbxX_Change(Win::Event& e) { soapEnvelope.SetParameterValue(L"x", tbxX.Text); ShowHttpRequest(); } void ClientCalculator::tbxY_Change(Win::Event& e) { soapEnvelope.SetParameterValue(L"y", tbxY.Text); ShowHttpRequest(); } void ClientCalculator::radioAddition_Click(Win::Event& e) { soapEnvelope.ActionName = L"Addition"; ShowHttpRequest(); } void ClientCalculator::radioSubtraction_Click(Win::Event& e) { soapEnvelope.ActionName = L"Subtraction"; ShowHttpRequest(); } void ClientCalculator::ShowHttpRequest() { Web::HttpRequest httpRequest; PrepareHttpRequest(httpRequest); wstring text; httpRequest.GetTextToBeSent(text); tbxHttpRequest.Text = text; } void ClientCalculator::PrepareHttpRequest(Web::HttpRequest& httpRequest) { httpRequest.Create(soapEnvelope); httpRequest.method = L"POST"; httpRequest.resource = L"/MathServer.dll"; // For Microsoft Visual Studio //httpRequest.resource = L"/MathServer/MathServer.dll"; // For Microsoft IIS } //____________________________________________________________ PROBLEM 3 void ClientCalculator::btCalculate_Click(Win::Event& e) { Win::BusyCursor busyCursor(true); wstring text; //_____________________________________________ 1. Send HTTP Request Web::HttpRequest httpRequest; PrepareHttpRequest(httpRequest); //_____________________________________________ 2. Show HTTP Request httpRequest.GetTextToBeSent(text); tbxHttpRequest.Text = text; //_____________________ Sys::Socket socket; int result = socket.Connect(L"localhost", 8080); // For Microsoft Visual Studio //int result socket.Connect(L"localhost", 80); // For Microsoft IIS if (result == SOCKET_ERROR) { tbxHttpResponse.ShowBalloonTip(L"ClientCalculator", socket.GetLastErrorDesc(), TTI_ERROR); return; } result = socket.Send(httpRequest); if (result == SOCKET_ERROR) { tbxHttpResponse.ShowBalloonTip(L"ClientCalculator", socket.GetLastErrorDesc(), TTI_ERROR); return; } if (result == SOCKET_DISCONNECTED) { tbxHttpResponse.ShowBalloonTip(L"Connection terminated", socket.GetLastErrorDesc(), TTI_ERROR); return; } socket.ShutdownSend(); //_____________________________________________ 3. Receive HTTP Response Web::HttpResponse httpResponse; result = socket.Receive(httpResponse); if (result == SOCKET_ERROR) { tbxHttpResponse.ShowBalloonTip(L"ClientCalculator", socket.GetLastErrorDesc(), TTI_ERROR); return; } //____________________________________________ 4. Display HTTP Response httpResponse.GetText(text); tbxHttpResponse.Text = text; //____________________________________________ 5. Extract Soap Envelope Sys::SoapEnvelope soapResult; const wchar_t* error = soapResult.CreateFromUtf8(httpResponse.body); if (error != NULL) { this->MessageBox(error, L"ClientCalculator", MB_OK | MB_ICONERROR); return; } //____________________________________________ 6. Display result soapResult.GetParameterValue(L"result", text); tbxResult.Text = text; } |
Step C |
Run the MathServer program previously created. Then run the ClientCalculator program. Test your program. You may also test the calculator using the Web Service that was published in Microsoft IIS. Ejecute el programa MathServer previamente creado. Entonces ejecute el programa ClientCalculator. Pruebe su programa. Usted también puede probar la calculadora usando el Web Service que fue publicado en Microsoft IIS. |
Problem 4 |
Repeat the previous problem using Java. This program has four classes:
Repita el problema anterior usando Java. Este programa tiene cuatro clases:
|
SoapParameter.java |
public class SoapParameter { public String name; public String value; public SoapParameter(String name, String value) { this.name = name; this.value = value; } } |
SoapEnvelope.java |
import java.util.Enumeration; import java.util.Vector; public class SoapEnvelope { private String methodName = null; private String xmlNameSpace = null; private int indentationLevel = 0; private String content = ""; public SoapEnvelope(String methodName, String xmlNameSpace) { this.methodName = methodName; this.xmlNameSpace = xmlNameSpace; indentationLevel = 0; content = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"; //________________________________________________________________________________ Envelope content += indentation(); content += "<soap:Envelope xmlns:soap=\"http://www.w3.org/2001/12/soap-envelope\" soap:encodingStyle=\"http://www.w3.org/2001/12/soap-encoding\">\r\n"; indentationLevel++; //________________________________________________________________________________ Body content += indentation(); content += "<soap:Body>\r\n"; indentationLevel++; //________________________________________________________________________________ Method content += indentation(); content += "<"; content += methodName; content += " xmlns=\""; content += xmlNameSpace; content += "\" >\r\n"; indentationLevel++; } public String getContent(Vector parameter) { String output = content; SoapParameter sp; //_______________________________________________________________________________ Parameter Enumeration param = parameter.elements(); while (param.hasMoreElements() == true) { sp = (SoapParameter)param.nextElement(); output += indentation(); output += "<"; output += sp.name; output += ">"; output += ToXml(sp.value); output += "</"; output += sp.name; output += ">\r\n"; } //________________________________________________________________________________ Method indentationLevel--; output += indentation(); output += "</"; output += methodName; output += ">\r\n"; //________________________________________________________________________________ Body indentationLevel--; output += indentation(); output += "</soap:Body>\r\n"; //________________________________________________________________________________ Envelope indentationLevel--; output += indentation(); output += "</soap:Envelope>\r\n"; return output; } public String indentation() { String out = ""; int i; for(i = 0; i < indentationLevel; i++) { out += " "; } return out; } public static String ToXml(String input) { final int len = input.length(); if (len == 0) return ""; String output =""; int i; for(i = 0; i < len; i++) { switch(input.charAt(i)) { // See the code in Wintempla > XML > XML } } return output; } } |
XmlHandler.java |
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.SAXException; import org.xml.sax.Attributes; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class XmlHandler extends org.xml.sax.helpers.DefaultHandler { public double result = 0.0; private boolean found = false; public XmlHandler() { result = 0.0; } public void startElement(String namespaceUri, String localName, String qualifiedName, Attributes attributes) throws SAXException { if (qualifiedName == "result") { found = true; } } public void endElement(String namespaceUri, String localName, String qualifiedName) throws SAXException { if (qualifiedName == "result") { found = false; } } public void characters(char[] chars, int startIndex, int endIndex) throws SAXException { if (found == true) { String value = new String(chars, startIndex, endIndex); try { result = Double.parseDouble(value); } catch(Exception ex) { } } } } |
ClientCalculatorJ.java |
import org.xml.sax.InputSource; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.net.*; import java.io.*; import java.util.Vector; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public class ClientCalculatorJ extends JFrame implements ActionListener { private JTextField tbxX; private JTextField tbxY; private JTextField tbxResult; private JTextArea tbxHttpRequest; private JTextArea tbxHttpResponse; private JButton btCalculate; public ClientCalculatorJ() { this.setTitle("ClientCalculatorJ"); this.setSize(600, 900); this.addWindowListener(new ExitListener()); //_______________________________________________________________ Top Panel JPanel paneTop = new JPanel(); paneTop.setLayout(new FlowLayout()); //______________________________________________ tbxX tbxX = new JTextField(10); paneTop.add(tbxX); //______________________________________________ + paneTop.add(new JLabel("+")); //______________________________________________ tbxY tbxY = new JTextField(10); paneTop.add(tbxY); //______________________________________________ = paneTop.add(new JLabel("=")); //______________________________________________ tbxResult tbxResult = new JTextField(10); paneTop.add(tbxResult); // btCalculate = new JButton("Calculate"); paneTop.add(btCalculate); btCalculate.addActionListener(this); //__________________________________________________________ Bottom Panel JPanel paneBottom = new JPanel(); paneBottom.setLayout(new GridLayout(2, 1, 5, 5)); //_____________________________________________ tbxHttpRequest tbxHttpRequest = new JTextArea(30, 30); paneBottom.add(tbxHttpRequest); //_____________________________________________ tbxHttpResponse tbxHttpResponse = new JTextArea(30, 30); paneBottom.add(tbxHttpResponse); //____________________________________________________________ Main Panel Container pane = this.getContentPane(); pane.setLayout(new BorderLayout()); pane.add(paneTop, BorderLayout.NORTH); pane.add(paneBottom, BorderLayout.CENTER); } public void actionPerformed(ActionEvent e) { if (e.getSource() == btCalculate) { //______________________________________________________________________ SOAP Envelope Vector parameter = new Vector<SoapParameter>(); parameter.add(new SoapParameter("x", tbxX.getText())); parameter.add(new SoapParameter("y", tbxY.getText())); SoapEnvelope se = new SoapEnvelope("Addition", "http://www.ugto.mx/MathServer"); String envelope = se.getContent(parameter); //______________________________________________________________________ Prepare HTTP Request //String httpRequest = "POST /MathServer.dll HTTP/1.0\r\n"; // Microsoft Visual Studio String httpRequest = "POST /MathServer/MathServer.dll HTTP/1.0\r\n"; // Microsoft IIS httpRequest += "Content-Type: application/soap+xml; charset=utf-8\n"; httpRequest += "Content-Length: "; httpRequest += envelope.length(); httpRequest += "\r\n\r\n"; // Empty Line indicates end of header httpRequest += envelope; tbxHttpRequest.setText(httpRequest); //______________________________________________________________________ Send HTTP Request tbxHttpResponse.setText(""); Socket socket = null; try { //________________________________ Connect Socket //socket = new Socket("localhost", 8080); // Microsoft Visual Studio socket = new Socket("localhost", 80); // Microsoft IIS PrintWriter output = new PrintWriter(socket.getOutputStream(), true); BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream())); //________________________________ Send HTTP Request //byte utf8HttpRequest[] = httpRequest.getBytes("UTF-8"); //output.write((char)utf8HttpRequest, utf8HttpRequest.length()); output.println(httpRequest); output.flush(); //________________________________ Receive HTTP Response String line; boolean isHeader = true; String xmlResponse = ""; while (true) { line = input.readLine(); if (line == null) break; if (isHeader == true && line.isEmpty() == true) isHeader = false; if (isHeader == false) { if (line.isEmpty() == false) { xmlResponse += line; xmlResponse += "\r\n"; } } tbxHttpResponse.append(line + "\r\n"); } socket.close(); //________________________________________________________________ Extract <result> from XML XmlHandler xmlHandler = new XmlHandler(); SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); InputSource inputSource = new InputSource(new StringReader(xmlResponse)); parser.parse(inputSource, xmlHandler); //tbxHttpResponse.setText(xmlResponse); tbxResult.setText(String.valueOf(xmlHandler.result)); //tbxHttpResponse.setText(xmlResponse); } catch(IOException ioe) { tbxHttpResponse.append("Exception: " + ioe.toString()+"\r\n"); } catch (Exception ex) { tbxHttpResponse.append("Exception: " + ex.toString()+"\r\n"); } } } public static void main(String[] args) { ClientCalculatorJ frame = new ClientCalculatorJ(); frame.pack(); frame.setVisible(true); } public class ExitListener extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } } |
Problem 5 |
Repeat the previous problem using Android. Do not use any library for Web Services, instead see the Android Examples in: Wintempla > Sockets > HTTP and Wintempla > XML . You must adapt the Java classes of the previous problem to Android. Your project must be called ClientCalculatorA. Do not forget to add the following line to the AndroidManifest.xml file: <uses-permission android:name="android.permission.INTERNET" /> Be sure to insert the uses-permission tag inside the manifest tag. Your project must include a set of classes to ease the creation of Web Services clients for Android. If you are using the Android emulator, the IP address of the personal computer (localhost) is 10.0.2.2. If you are not using threads, add the following to onCreate StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitNetwork().build()); Repita el problema anterior usando Android. No utilice ninguna librería para Web Services, en su lugar vea los ejemplos de Android en: Wintempla > Sockets > HTTP y Wintempla > XML . Usted debe adaptar las clases de Java del problema anterior a Android. Su proyecto debe ser llamado ClientCalculatorA. No se olvide de agregar la línea siguiente al archivo AndroidManifest.xml: <uses-permission android:name="android.permission.INTERNET" /> Asegúrese de insertar la etiqueta de uses-permission dentro de la etiqueta manifest. Su proyecto debe incluir un conjunto de clases para facilitar la creación de clientes para Web Services en Android. Si usted está usando el emulador de Android, la dirección IP de la computadora local (localhost) es 10.0.2.2. Si usted no está usando hilos, agregue lo siguiente a onCreate StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitNetwork().build()); |
Problem 6 |
Repeat the previous problem using Android. Use the KSOAP2 library. Your project must be called ClientCalculatorAK. DO NOT check AppCompatActivity when creating the project. Do not forget to add the following line (insert this line before the <application node) to the AndroidManifest.xml file: <uses-permission android:name="android.permission.INTERNET" /> If you are not using threads, add the following to onCreate StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitNetwork().build()); Repita el problema anterior usando Android. Utilice la librería KSOAP2. Su proyecto debe ser llamado ClientCalculatorAK. NO marque la opción de AppCompatActivity al crear el proyecto. No se olvide de agregar la línea siguiente (inserte esta linea ante del nodo <application) al archivo AndroidManifest.xml: <uses-permission android:name="android.permission.INTERNET" /> Si usted no está usando hilos, agregue la siguiente línea a onCreate StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitNetwork().build()); |
Step A |
Download KSOAP2 and copy the JAR file to the libs folder in your project. Observe that this version of KSOAP includes its dependencies. Descargue KSOAP2 y copie el archivo JAR a la carpeta de libs de su proyecto. Observe que esta versión de KSOAP incluye sus dependencias. |
Step B |
From Android Studio, click as shown to open "Project Files". Then, select the KSOAP2 jar file. Desde Android Studio, haga clic como se muestra para abrir "Project Files". Entonces seleccione el archivo jar de KSOAP. |
Step C |
Use the context menu (select the KSOAP jar file, then right click) to add the library to your project. Try to use KSOAP2-Android-assembly-3.6.2 or later (http://oss.sonatype.org). Use el menú de contexto (seleccione el archivo jar de KSOAP, entonces haga clic con el botón derecho del ratón) para agregar la librería a su proyecto. Trate de usar KSOAP2-Android-assembly-3.6.2 o posterior (http://oss.sonatype.org). |
Step D |
Edit the MainActivity.java file as shown. Edite el archivo MainActivity.java como se muestra. |
MainActivity.java |
package com.example.sergio.clientcalculatorak; import android.os.StrictMode; import android.app.Activity; //import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.EditText; import org.ksoap2.SoapEnvelope; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.ksoap2.transport.HttpTransportSE; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //______ Allow main thread to run sockets (DO NOT use in production) StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitNetwork().build()); } public void btAdd_onClick(View view) { CallWebService("Addition"); } public void btSubtract_onClick(View view) { CallWebService("Subtraction"); } private void CallWebService(String actionName) { EditText tbxX = (EditText)findViewById(R.id.tbxX); EditText tbxY = (EditText)findViewById(R.id.tbxY); EditText tbxResult = (EditText)findViewById(R.id.tbxResult); //__________________________________________________________________ SOAP SoapObject request = new SoapObject("http://www.ugto.mx/MathServer", actionName); request.addProperty("x",tbxX.getText().toString()); request.addProperty("y",tbxY.getText().toString()); //___________________________________________________________________ SOAP Version 1.2 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12); envelope.setOutputSoapObject(request); envelope.dotNet = true; try { //Emulator: 10.0.2.2, Device: IP address of the server //HttpTransportSE httpTransport = new HttpTransportSE("http://10.0.2.2:8080/MathServer.dll"); // Microsoft Visual Studio HttpTransportSE httpTransport = new HttpTransportSE("http://10.0.2.2/MathServer/MathServer.dll"); // Microsoft IIS httpTransport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); httpTransport.debug = true; // Inspect: httpTransport.requestDump and httpTransport.responseDump httpTransport.call(actionName, envelope); //______________________________________________________________ Get and Display result SoapObject result = (SoapObject)envelope.bodyIn; if(result != null) { tbxResult.setText(result.getProperty(0).toString()); // int numRows = result.getPropertyCount(); // SoapObject row = result.getProperty(row_index); // String col0 = new String(row.getProperty(col_index).toString()); } } catch (Exception e) { tbxResult.setText(e.toString()); } } } |
Problem 7 |
Publish in a Web Server the MathServer Web Service. Use Basic Authentication. We will add a Username and a Password to access the Web Services. Publique en un Servidor Web el Web Service llamado MathServer. Use Autenticación Básica. Agregaremos un Username y un Password para accesar los Servicios Web. |
Step 1 |
Open Microsoft IIS. Then Select the MathServer folder, click on Authentication. Disable Anonymous Authentication and Enable Basic Authentication. Abra Microsoft IIS. Entonces seleccione la carpeta de MathServer folder, haga clic en Authentication. Deshabilite Autentificación Anónima y habilite Autentificación Básica. |
Step 2 |
Create a user following the instruction at: Wintempla > Publishing a Web Site > Private Web Site Cree un usuario siguiendo las instrucciones en: Wintempla > Publishing a Web Site > Private Web Site |
Step 3 |
You may optionally use the variable AUTH_USER to know what user is connected. Usted puede opcionalmente usar la variable AUTH_USER para saber que usuario está conectado. |
Addition.cpp |
. . . void Addition::Window_Open(Web::HttpConnector& h) { //______________________________________________________ Username wstring username; if (h.GetServerVariable("AUTH_USER", username) == false) return; // Instead of AUTH_USER, you may use LOGON_USER const double x = serviceAddition.GetDoubleParameter(h, L"x"); const double y= serviceAddition.GetDoubleParameter(h, L"y"); serviceAddition.soapEnvelope.AddParameter(L"result", x+y); } |
Subtraction.cpp |
void Subtraction::Window_Open(Web::HttpConnector& h) { //______________________________________________________ Username wstring username; if (h.GetServerVariable("AUTH_USER", username) == false) return; // Instead of AUTH_USER, you may use LOGON_USER const double x = serviceSubtraction.GetDoubleParameter(h, L"x"); const double y= serviceSubtraction.GetDoubleParameter(h, L"y"); serviceSubtraction.soapEnvelope.AddParameter(L"result", x-y); } |
Problem 8 |
Open the ClientCalculator project. Add a Dialog called LoginDlg to the ClientCalculator project: Tools > Add Wintempla Item... > Dialog . Abra el proyecto ClientCalculator. Agregue un diálogo llamado LoginDlg al proyecto de ClientCalculator: Tools > Add Wintempla Item... > Dialog . |
Step A |
Include the file LoginDlg.h in the file ClientCalculator.h. Incluya el archivo LoginDlg.h en el archivo ClientCalculator.h. |
ClientCalculator.h |
#pragma once //______________________________________ ClientCalculator.h #include "Resource.h" #include "LoginDlg.h" . . . |
Step B |
Edit the files: LoginDlg.h and LoginDlg.cpp. In this case, we will make public the GUI elements by removing the keyword private. Edite los archivos: LoginDlg.h y LoginDlg.cpp. En este caso, haremos públicos los elementos GUI removiendo la palabra private. |
LoginDlg.h |
#pragma once //_____________________________________________ LoginDlg.h #include "resource.h" class LoginDlg: public Win::Dialog { public: LoginDlg() { } ~LoginDlg() { } //private: //______ Wintempla GUI manager section begin: DO NOT EDIT AFTER THIS LINE . . . }; |
LoginDlg.cpp |
. . . void LoginDlg::btOK_Click(Win::Event& e) { this->EndDialog(TRUE); } void LoginDlg::btCancel_Click(Win::Event& e) { this->EndDialog(FALSE); } |
Step C |
Edit the file ClientCalculator.cpp Edite el archivo ClientCalculator.cpp |
ClientCalculator.cpp |
. . . void ClientCalculator::PrepareHttpRequest(Web::HttpRequest& httpRequest) { httpRequest.Create(soapEnvelope); httpRequest.method = L"POST"; //httpRequest.resource = L"/MathServer.dll"; // For Microsoft Visual Studio httpRequest.resource = L"/MathServer/MathServer.dll"; // For Microsoft IIS } void ClientCalculator::btCalculate_Click(Win::Event& e) { LoginDlg dlg; if (dlg.BeginDialog(hWnd) == FALSE) return; // User Cancelled // Win::BusyCursor busyCursor(true); wstring text; //_____________________________________________ 1. Send HTTP Request Web::HttpRequest httpRequest; PrepareHttpRequest(httpRequest); httpRequest.SetUsernameAndPassword(dlg.tbxUsername.Text, dlg.tbxPassword.Text); //_____________________________________________ 2. Show HTTP Request httpRequest.GetTextToBeSent(text); tbxHttpRequest.Text = text; //_____________________ Sys::Socket socket; . . . } |
Problem 9 |
Create a IIS Web Server Application to list the staff in the univ database, see Wintempla > SQL > Sample Databases. The application must be called StaffList. The Web Service to list the staff is called StaffSelect. Cree una IIS Web Server Application para listar el Personal de la base de datos univ, vea Wintempla > SQL > Sample Databases. El programa debe llamarse StaffList. El Web Service para listar el personal se llama StaffSelect. |
Step A |
In the Index.cpp Web page insert a Button to navigate to the Web page StaffSelect. En la página Web Index.cpp inserte un botón para navegar a la página Web StaffSelect. |
Index.cpp |
. . . void Index::btStaffSelect_onclick(Web::HttpConnector& h) { h.NavigateTo(L"StaffSelect"); } |
Step B |
Edit the string connection in the file stdafx.h Edite la cadena de conexión en el archivo stdafx.h |
stdafx.h |
. . . #define CONNECTION_STRING L"DRIVER={SQL Server};server=localhost\\SQLEXPRESS;database=univ;Trusted_Connection=yes" |
Step C |
Insert a Web page called StaffSelect using Tools > Add Wintempla Item... Do not forget to include the file StaffSelect.h at the top of the file StaffList.cpp. Inserte una Web page llamada StaffSelect using Tools > Add Wintempla Item... No se olvide de incluir el archivo StaffSelect.h en la parte de arriba del archivo StaffList.cpp. |
StaffList.cpp |
#include "stdafx.h" //________________________________________ StaffList.cpp #include "StaffList.h" #include "StaffSelect.h" . . . |
Step D |
Insert a Web Service called StaffSelect in the file StaffSelect.cpp. Inserte un Web Service llamado StaffSelect en el archivo StaffSelect.cpp. |
Step E |
Edit the file StaffList.cpp. You may use the Wintempla templates (located in the Toolbox) by pressing Ctrl+Alt-X; in this case SQL: SELECT listView can be used. Drag the template to the file, and then edit the file. Observe that the SqlConnection will insert data into the SOAP envelope. If you provide a sample node, then ExecuteSelect will insert nodes equal to this one. If you do not provide a sample node, then ExecuteSelect will create generic names for all nodes. Edite el archivo StaffList.cpp. Usted puede usar las plantillas de Wintempla (localizadas en las Herramientas o Toolbox) presionado Ctrl+Alt+X; en este caso SQL: SELECT listView puede ser usada. Arrastre la plantilla al archivo, y entonces edite el archivo. Observe que SqlConnection insertará datos en el sobre de SOAP. Si usted proporciona un nodo de muestra, entonces ExecuteSelect insertará nodos iguales a este. Si usted no proporciona un nodo muestra, entonces ExecuteSelect creará nombres genéricos para todos los nodos. |
StaffSelect.cpp |
. . . void StaffSelect::Window_Open(Web::HttpConnector& h) { serviceStaffSelect.soapEnvelope.ActionXmlns = L"http://www.ugto.mx/StaffList"; //_______________ Prepare a sample XML node, so that ExecuteSelect create the rest of the nodes like this one list<Sys::Xml>::iterator response; if (serviceStaffSelect.soapEnvelope.GetResponse(response) == false) return; Sys::Xml& staff = response->AddChild(L"staff"); staff.AddChild(L"staff_id"); staff.AddChild(L"last_name"); staff.AddChild(L"first_name"); staff.AddChild(L"position"); staff.AddChild(L"salary"); Sql::SqlConnection conn; try { //conn.OpenSession(DSN, USERNAME, PASSWORD); //Control Panel>Administrative Tools>Data Sources (ODBC)>Create dsn_myDatabase conn.OpenSession(NULL, CONNECTION_STRING); conn.ExecuteSelect(L"SELECT staff_id, last_name, first_name, position, salary FROM staff", 100, serviceStaffSelect.soapEnvelope); } catch (Sql::SqlException e) { this->MessageBox(e.GetDescription(), L"Error", MB_OK | MB_ICONERROR); } } |
Problem 10 |
Publish in a Web Server the StaffSelect Web Service. Use Anonymous Authentication, see Publishing a Web Site > Public SQL Web site (You must edit the univ.sql file to give permission to IIS AppPool\sales, if sales is name of the application pool for the web site). Publique en un Servidor Web el Web Service llamado StaffSelect. Use Autentificación Anónima, vea Publishing a Web Site > Public SQL Web site . (Usted debe editar el archivo univ.sql para dar permiso a IIS AppPool\sales, si sales es el nombre de la application pool para este sitio web). |
Problem 11 |
Create a Dialog Application called UnivClient to access the Web Service of the previous problem. Remember to remove the comment from #define WIN_SOCKETS_SUPPORT in the file stdafx.h. Edit the program GUI as shown. To show the HTTP Request and the HTTP Response use a multiline textbox with vertical and horizontal scrollbars. Cree una Aplicación de Diálogo llamada UnivClient para accesar el Web Service del problema anterior. Recuerde remover los comentarios de #define WIN_SOCKETS_SUPPORT en el archivo stdafx.h. Edite la GUI del programa como se muestra. Para mostrar la HTTP Request y la HTTP Response use una caja de texto multi-línea con barras de desplazamiento vertical y horizontal. |
UnivClient.cpp |
. . . void UnivClient::Window_Open(Win::Event& e) { Win::BusyCursor busyCursor(true); wstring text; //_________________________________________________________ 1. Soap Envelope setup Sys::SoapEnvelope soapEnvelope; soapEnvelope.ActionXmlns = L"http://www.ugto.mx/StaffList"; soapEnvelope.ActionName = L"StaffSelect"; //_________________________________________________________ 2. Prepare HTTP Request Web::HttpRequest httpRequest; httpRequest.Create(soapEnvelope); httpRequest.method = L"POST"; httpRequest.resource = L"/StaffList.dll"; // For Microsoft Visual Studio //httpRequest.resource = L"/StaffList/StaffList.dll"; // For Microsoft IIS httpRequest.GetText(text); tbxHttpRequest.Text = text; //________________________________________________________ 3. Send HTTP Request Sys::Socket socket; if (socket.Connect(L"localhost", 8080) == SOCKET_ERROR) // For Microsoft Visual Studio //if (socket.Connect(L"localhost", 80) == SOCKET_ERROR) // For Microsoft IIS { tbxHttpResponse.ShowBalloonTip(L"UnivClient", socket.GetLastErrorDesc(), TTI_ERROR); return; } int result = socket.Send(httpRequest); if (result == SOCKET_ERROR) { tbxHttpResponse.ShowBalloonTip(L"UnivClient", socket.GetLastErrorDesc(), TTI_ERROR); return; } if (result == SOCKET_DISCONNECTED) { tbxHttpResponse.ShowBalloonTip(L"Connection terminated", socket.GetLastErrorDesc(), TTI_ERROR); return; } socket.ShutdownSend(); //_________________________________________________________ 4. Receive HTTP Response Web::HttpResponse httpResponse; result = socket.Receive(httpResponse); if (result == SOCKET_ERROR) { tbxHttpResponse.ShowBalloonTip(L"UnivClient", socket.GetLastErrorDesc(), TTI_ERROR); return; } //_________________________________________________________ 5. Display HTTP Response httpResponse.GetText(text); tbxHttpResponse.Text = text; //_________________________________________________________ 6. Extract Soap Envelope Sys::SoapEnvelope soapResult; const wchar_t* error = soapResult.CreateFromUtf8(httpResponse.body); if (error != NULL) { this->MessageBox(error, L"UnivClient", MB_OK | MB_ICONERROR); return; } //_________________________________________________________ 7. Display Results list<Sys::Xml>::iterator response; if (soapResult.GetResponse(response) == false) return; lvStaff.ImportFromXml(false, *response); } |
Tip |
Web Services do not require any Internet browser. Web Services do not require Javascript nor HTML. However, Web Services use HTTP and a Web Server. Los Servicios Web no requieren de ningún explorador de la Internet. Los Servicios Web no requieren Javascript ni HTML. Sin embargo, los servicios Web usan HTTP y un servidor Web. |
Problem 12 |
Create a Web Service to send and receive messages (assume that the client cannot access any SQL Server, it can only connect to a Web Server). The Web Service will provide five methods:
Crear un Servicio Web para enviar y recibir mensajes entre usuarios (asuma que el cliente no se puede conectar a ningún Servidor de SQL; el cliente sólo puede conectarse a un Servidor Web). El Servicio Web soportará cinco métodos (servicios):
|
Project Steps |
|
Tip |
Desktop application organization (Main Window and Add message dialog)
Organización de la aplicación de escritorio (Ventana principal y diálogo de agregar mensaje)
|
Tip |
Android application organization (Login Activity, Contact Activity, Message Activity, New Message Activity)
Organización de la aplicación para Android (Activity para Login, Activity para contactos, Activity para mensajes, Activity para mensajes nuevos)
|
Problem 13 |
Create Web Application using Wintempla called MyGraph. After creating the application, insert a XyChart in the Index web page. Run the program and use your Computer Science skills to find out what HTML tags are used to create the chart in the web page. Cree una Aplicación Web usando Wintempla llamada MyGraph. Después de crear la aplicación, inserte una XyChart en la página web Index. Ejecute el programa y use sus habilidades de Ciencias de la Computación para averiguar que etiquetas de HTML son usadas para crear la gráfica en la página web. |